package com.megagoodsoftware.smugmug;

import java.io.*;
import java.util.*;

import android.util.*;

import com.megagoodsoftware.smugmug.CountingHttpEntity.*;
import com.megagoodsoftware.smugmug.exceptions.*;

public class SmugMug {

	private SmugMugClient client;
	private HashMap<String, SmugMugCategory> categories;
	private HashMap<String, SmugMugAlbum> albums;
	private SmugMugAccount account;

	public SmugMug(int userId, String hashPassword)
	throws SmugMugBadAuthentication, SmugMugInternalError {
		this(new SmugMugClient(), userId, hashPassword);
	}
	public SmugMug(SmugMugClient client, int userId, String hashPassword)
	throws SmugMugBadAuthentication, SmugMugInternalError {
		this.client = client;
		loginWithHash(userId, hashPassword);
		try {
			updateCache();
		} catch (SmugMugFailedResponse e) {
			String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
			Log.e(Constants.TAG, msg);
			throw new SmugMugInternalError(msg);
		}
	}

	public SmugMug(String email, String password) throws SmugMugInternalError, SmugMugFailedResponse {
		this(new SmugMugClient(), email, password);
	}

	public SmugMug(SmugMugClient client, String email,
			String password) throws SmugMugInternalError, SmugMugBadAuthentication {
		this.client = client;
		loginWithPassword(email, password);
		try {
			updateCache();
		} catch (SmugMugFailedResponse e) {
			String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
			Log.e(Constants.TAG, msg);
			throw new SmugMugInternalError(msg);
		}
	}

	public SmugMug(SmugMugAccount acct) throws SmugMugInternalError, SmugMugBadAuthentication {
		account = acct;
		client = new SmugMugClient();
		try {
			updateCache();
		} catch (SmugMugFailedResponse e) {
			String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
			Log.e(Constants.TAG, msg);
			throw new SmugMugInternalError(msg);
		}
		
	
	}
	public SmugMug() {
		
	}
	public SmugMug(SmugMugClient client) {
		this.client = client;
	}
	public void loginWithPassword(String email, String password) throws SmugMugBadAuthentication, SmugMugInternalError {
		getClientIfNecessary();
		account = client.login(email, password);
		Log.i(Constants.TAG, account.toString());
	}
	public void updateCache() throws SmugMugInternalError, SmugMugFailedResponse {
		Log.d(Constants.TAG, "updating cache");
		try {
			categories = client.getAllCategories(account.getSession());
			albums = client.getAllAlbums(account.getSession());
		} catch (SmugMugFailedResponse e) {
			String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
			Log.w(Constants.TAG, msg);
			throw e;
		} catch (Exception e) {
			Log.e(Constants.TAG, "uncaught exception", e);
			throw new SmugMugInternalError("uncaught exception: " + e.getLocalizedMessage());
		}
	}
	public void loginWithHash(int userId, String hashPassword)
	throws SmugMugBadAuthentication, SmugMugInternalError {
		getClientIfNecessary();
		account = client.login(userId, hashPassword);
		Log.i(Constants.TAG, account.getSession());
	}

	private void getClientIfNecessary() {
		if (client == null) {
			client = new SmugMugClient();
		}
	}
	public ArrayList<SmugMugAlbum> getAlbums() {
		return new ArrayList<SmugMugAlbum>(albums.values());
	}

	public SmugMugImage upload(ProgressListener listener, InputStream is, String md5, SmugMugAlbum album, String name) throws SmugMugConnectionError, SmugMugFailedResponse, SmugMugInternalError {
		SmugMugImage image = client.upload(listener, is, md5, account.getSession(), album, name);
		album.addImage(image);
		return image;
	}

	public ArrayList<SmugMugAlbum> getAlbums(String title) {
		ArrayList<SmugMugAlbum> albums = new ArrayList<SmugMugAlbum>();
		for (Iterator<SmugMugAlbum> it = getAlbums().iterator(); it.hasNext(); )
		{
			SmugMugAlbum currentAlbum = it.next();
			if (currentAlbum.getTitle().equals(title))
				albums.add(currentAlbum);
		}
		return albums;
	}

	public SmugMugAlbum getAlbum(int id) {
		return albums.get(Integer.toString(id));
	}
	public boolean logout() {
		boolean loggedOut = client.logout(account.getSession());
		Log.i(Constants.TAG, "logged out successfully");
		return loggedOut;
	}
	
	public SmugMugCategory getCategory(int id) {
		return categories.get(Integer.toString(id));
	}
	
	// package default scope
	String getSession() {
		return account.getSession();
	}
	
	public ArrayList<SmugMugCategory> getCategories() {
		return new ArrayList<SmugMugCategory>(categories.values());
	}
	public SmugMugAccount getAccount() {
		return account;
	}
	public void updateCache(SmugMugAlbum album) throws SmugMugInternalError, SmugMugFailedResponse {
		Log.d(Constants.TAG, "updating cache in album " + album.getTitle());
		try {
			client.updateImages(account.getSession(), album);
		} catch (SmugMugFailedResponse e) {
			String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
			Log.w(Constants.TAG, msg);
			throw e;
		} catch (Exception e) {
			Log.e(Constants.TAG, "uncaught exception", e);
			throw new SmugMugInternalError("uncaught exception: " + e.getLocalizedMessage());
		}
	}
	public void setClient(SmugMugClient client) {
		this.client = client;
	}
}
